﻿#include "protocoleditor.h"
#include "ui_protocoleditor.h"


ProtocolEditor::ProtocolEditor(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::ProtocolEditor)
{
    ui->setupUi(this);

    QString dirPath = QCoreApplication::applicationDirPath()+"/Systems";
    QDir dir(dirPath);
    if(!dir.exists())
    {
       dir.mkdir(dirPath);
    }

    Initialization();
}

ProtocolEditor::~ProtocolEditor()
{
    delete ui;
}

void ProtocolEditor::Initialization()
{
    QIcon icon;
    icon.addPixmap(QPixmap(QString(":Icon/ICON_4_1.ico")));
    setWindowIcon(icon);
    setWindowTitle("协议编辑器");

    InittProtocolSysPanel("SysView");
    InitProtocolSubSysPanel("MsgView");
    InitSubSysDataPanel("DataView");
    InitToolBarEvent();

    auto DataInfoView = FindDataInfoViewByName("DataInfoView");
    if(nullptr == DataInfoView) return;
    QPalette pa = DataInfoView->palette();
    DataInfoView->setReadOnly(true);
    pa.setColor(QPalette::Base,QColor(162,181,205));
    DataInfoView->setPalette(pa);
    DataInfoView->setFont(QFont("Microsoft YaHei", 11));

    connect(DataInfoView,SIGNAL(cursorPositionChanged()),this,SLOT(onCurrentLineHighLight()));
    LoadSystemFile(GetSysFilePath());
    connect(&m_FindEditor,SIGNAL(sendFindReult(int,int,int)),this,SLOT(on_RecvFindRes(int,int,int)));

    connect(&m_SysEditor,SIGNAL(on_CreateSysProtocol(int,const QString)),this,SLOT(on_CreateSysProtocolSlot(int,const QString)));
    connect(&m_SysEditor,SIGNAL(on_EditorSysProtocol(int,const QString,int)),this,SLOT(on_EditorSysProtocolSlot(int,const QString,int)));

    connect(&m_SysSubEditor,SIGNAL(on_CreateSysSubProtocol(int,const QString,int)),this,SLOT(on_CreateSysSubProtocolSlot(int,const QString,int)));
    connect(&m_SysSubEditor,SIGNAL(on_EditorSysSubProtocol(int,const QString,int,int)),this,SLOT(on_EditorSysSubProtocolSlot(int,const QString,int,int)));

    connect(&m_SubDataEditor,SIGNAL(on_CreateSubDataProtocol(int,const QString,const QString)),this,SLOT(on_CreateSubDataProtocolSlot(int,const QString,const QString)));
    connect(&m_SubDataEditor,SIGNAL(on_EditorSubDataProtocol(int,const QString,const QString)),this,SLOT(on_EditorSubDataProtocolSlot(int,const QString,const QString)));
}

void ProtocolEditor::InittProtocolSysPanel(const QString sName)
{
    auto SysView = FindViewItemByName(sName);
    if(nullptr == SysView) return;

    SysView->setColumnCount(2);
    SysView->setHorizontalHeaderLabels(QStringList()<<"<系统ID>"<<"<系统名称>");
    SysView->setSelectionBehavior(QAbstractItemView::SelectRows);       //行选择
    SysView->setEditTriggers(QAbstractItemView::NoEditTriggers);   //禁止修改
    SysView->verticalHeader()->setVisible(false);                        //隐藏列表头
    SysView->setSelectionMode(QAbstractItemView::SingleSelection );     //选择一行
    SysView->setColumnWidth(0, 70);                                             //行宽高
    SysView->setStyleSheet("selection-background-color:gray");  //设置选中行颜色
    SysView->setSortingEnabled(false);                                          //自动排序
    SysView->horizontalScrollBar()->setHidden(true);                    //隐藏横向scrollBar
    SysView->setFont(QFont("Microsoft YaHei", 9));                  //字体
    SysView->horizontalHeader()->setStretchLastSection(true);       //自适应调整
    SysView->verticalHeader()->setDefaultSectionSize(18);
    SysView->setAlternatingRowColors(true);
    SysView->setWordWrap(false);
    SysView->horizontalHeader()->setHighlightSections(false);
    SysView->viewport()->installEventFilter(this);
    connect(SysView->horizontalHeader(),SIGNAL(sectionClicked(int )),this, SLOT(sortSysTableByCol(int)));
}

void ProtocolEditor::InitProtocolSubSysPanel(const QString sName)
{
    auto SubView = FindViewItemByName(sName);
    if(nullptr == SubView) return;

    SubView->setColumnCount(3);
    SubView->setHorizontalHeaderLabels(QStringList()<<"<子系统ID>"<<"<子系统名称>"<<"<信息来源>");
    SubView->setSelectionBehavior(QAbstractItemView::SelectRows);
    SubView->setEditTriggers(QAbstractItemView::NoEditTriggers);   //禁止修改
    SubView->verticalHeader()->setVisible(false);                   //隐藏列表头
    SubView->setSelectionMode(QAbstractItemView::SingleSelection);
    SubView->setAlternatingRowColors(true);
    SubView->setSortingEnabled(false);
    SubView->horizontalScrollBar()->setHidden(true);
    SubView->setSelectionMode(QAbstractItemView::SingleSelection);
    SubView->setColumnWidth(0, 70);
    SubView->setColumnWidth(1, 120);
    SubView->setFont(QFont("Microsoft YaHei", 9));
    SubView->horizontalHeader()->setStretchLastSection(true);
    SubView->verticalHeader()->setDefaultSectionSize(18);
    SubView->setStyleSheet("selection-background-color:gray");  //设置选中行颜色
    SubView->resizeRowsToContents();
    SubView->setGridStyle(Qt::DashDotDotLine);
    SubView->setWordWrap(false);            //文本不自动换行
    SubView->horizontalHeader()->setHighlightSections(false);
    SubView->viewport()->installEventFilter(this);
    connect(SubView->horizontalHeader(),SIGNAL(sectionClicked(int )),this, SLOT(sortSubTableByCol(int)));

    ui->upBtn->setIcon(QIcon(":Icon/up.png"));
    ui->downBtn->setIcon(QIcon(":Icon/down.png"));
}

void ProtocolEditor::InitSubSysDataPanel(const QString sName)
{
    auto DataView = FindViewItemByName(sName);
    if(nullptr == DataView) return;

    DataView->setColumnCount(2);
    DataView->setHorizontalHeaderLabels(QStringList()<<"<类型>"<<"<意义描述>"<<"");
    DataView->setSelectionBehavior(QAbstractItemView::SelectRows);
    DataView->setEditTriggers(QAbstractItemView::NoEditTriggers);   //禁止修改
    DataView->verticalHeader()->setVisible(false);   //隐藏列表头
    DataView->setSelectionMode(QAbstractItemView::SingleSelection);

    DataView->setFont(QFont("Microsoft YaHei", 9));
    DataView->horizontalHeader()->setStretchLastSection(true);
    DataView->verticalHeader()->setDefaultSectionSize(18);
    DataView->setStyleSheet("selection-background-color:gray");  //设置选中行颜色
    DataView->resizeRowsToContents();
    DataView->setGridStyle(Qt::DashDotDotLine);
    DataView->setWordWrap(false);            //文本不自动换行
    DataView->horizontalHeader()->setHighlightSections(false);

    DataView->setSortingEnabled(false);
    DataView->horizontalScrollBar()->setHidden(true);

    DataView->horizontalHeader()->setSectionsClickable(false);    //水平方向的头不可点击
    DataView->verticalHeader()->setSectionsClickable(false);      //垂直方向的头不可点击
    DataView->viewport()->installEventFilter(this);
}

void ProtocolEditor::InitToolBarEvent()
{
    QAction *pExitAction = ui->Quit_Act;
    connect(pExitAction,&QAction::triggered,[]{exit(0);});

    //查找面板事件
    QAction *pFindAction = ui->Find_Act;
    connect(pFindAction,&QAction::triggered,[this]
    {
        m_FindEditor.setWindowModality(Qt::ApplicationModal);
        m_FindEditor.reset();
        m_FindEditor.show();
    }
    );


    //添加系统事件
    QAction *pAddSysAction = ui->AddSys_Act;
    connect(pAddSysAction,&QAction::triggered,[this]
    {
        m_SysEditor.InitSysProtocolEditor(ADD_DATA);
        m_SysEditor.setWindowModality(Qt::ApplicationModal);
        m_SysEditor.show();
    }
    );
    QAction *pEditSysAction = ui->EditorSys_Act;
    connect(pEditSysAction,&QAction::triggered,[this]
    {
        //是否有选中系统，没有不可操作
        auto DataView = FindViewItemByName("SysView");
        if(nullptr == DataView || DataView->selectedItems().count() == 0) return;

        auto pItem1 = DataView->selectedItems().at(0);
        auto pItem2 = DataView->selectedItems().at(1);
        if(nullptr == pItem1 || nullptr == pItem2) return;

        int nId      = pItem1->data(Qt::DisplayRole).toInt();
        QString sMsg = pItem2->text();
        sMsg = sMsg.mid(2,sMsg.length()-4);
        m_SysEditor.InitSysProtocolEditor(EDIT_DATA,nId,sMsg);
        m_SysEditor.setWindowModality(Qt::ApplicationModal);
        m_SysEditor.show();
    }
    );


    //添加消息事件
    QAction *pAddSubAction = ui->AddMsg_Act;
    connect(pAddSubAction,&QAction::triggered,[this]
    {
        //是否有选中系统，没有不可操作
        auto DataView = FindViewItemByName("SysView");
        if(nullptr == DataView || DataView->selectedItems().count() == 0) return;
        m_SysSubEditor.InitSysSubProtocolEditor(ADD_DATA);
        m_SysSubEditor.setWindowModality(Qt::ApplicationModal);
        m_SysSubEditor.show();
    }
    );
    QAction *pEditSubAction = ui->EditMsg_Act;
    connect(pEditSubAction,&QAction::triggered,[this]
    {
        //是否有选中系统，没有不可操作
        auto DataView = FindViewItemByName("SysView");
        if(nullptr == DataView || DataView->selectedItems().count() == 0) return;

        auto SubView = FindViewItemByName("MsgView");
        if(nullptr == SubView || SubView->selectedItems().count() == 0) return ;

        int nId = SubView->selectedItems().at(0)->data(Qt::DisplayRole).toInt();
        int nMsgType = SubView->selectedItems().at(0)->type();
        QString sMsg = SubView->selectedItems().at(1)->text();

        m_SysSubEditor.InitSysSubProtocolEditor(EDIT_DATA,nId,nMsgType,sMsg);
        m_SysSubEditor.setWindowModality(Qt::ApplicationModal);
        m_SysSubEditor.show();
    }
    );


    //添加数据事件 //是否有选中消息没有不可以操作
    QAction *pAddSubDataAction = ui->AddData_Act;
    connect(pAddSubDataAction,&QAction::triggered,[this]
    {

        auto SysView = FindViewItemByName("SysView");
        if(nullptr == SysView || SysView->selectedItems().count() == 0) return;

        auto SubView = FindViewItemByName("MsgView");
        if(nullptr == SubView || SubView->selectedItems().count() == 0) return ;

        m_SubDataEditor.InitSubDataProtocolEditor(ADD_DATA);
        m_SubDataEditor.setWindowModality(Qt::ApplicationModal);
        m_SubDataEditor.show();
    }
    );

    QAction *pEditSubDataAction = ui->EditData_Act;
    connect(pEditSubDataAction,&QAction::triggered,[this]
    {
        auto SysView = FindViewItemByName("SysView");
        if(nullptr == SysView || SysView->selectedItems().count() == 0) return;

        auto SubView = FindViewItemByName("MsgView");
        if(nullptr == SubView || SubView->selectedItems().count() == 0) return ;

        auto DataView = FindViewItemByName("DataView");
        if(nullptr == DataView || DataView->selectedItems().count() == 0) return ;

        int nType = DataView->selectedItems().at(0)->type();
        QString sInfo = DataView->selectedItems().at(1)->text();
        auto DataInfoView = FindDataInfoViewByName("DataInfoView");
        if(nullptr == DataInfoView) return;
        QString sMsg = DataInfoView->toPlainText();

        m_DataOldData.nType =nType;
        m_DataOldData.sData = sInfo;
        m_DataOldData.sInfo =sMsg;
        m_SubDataEditor.InitSubDataProtocolEditor(EDIT_DATA,nType,sInfo,sMsg);
        m_SubDataEditor.setWindowModality(Qt::ApplicationModal);
        m_SubDataEditor.show();
    }
    );


    //关于事件
    QAction * pAboutAction = ui->About_Act;
    connect(pAboutAction,&QAction::triggered,
            []
    {
        QDialog dia;
        dia.setWindowTitle("说明");
        dia.setWindowIcon(QIcon(":Icon/About.png"));
        QHBoxLayout* btnLayout = new QHBoxLayout(&dia);
        QTextEdit* editor = new QTextEdit(&dia);
        editor->setAlignment(Qt::AlignCenter);
        editor->setText("协议编辑器v1.1\n\t\t  By:  TZY\n\t\t  UpateTime:\t\t\t  2021-06-25");
        editor->setStyleSheet("background-image:url(:/Icon/aB.jpg);\n"
                              "background-attachment:fixed;\n"
                              "background-repeat:none;\n"
                              "background-position:center");
        editor->setFont(QFont(tr("仿宋"), 13));
        editor->setReadOnly(true);
        btnLayout->addWidget(editor);
        dia.setLayout(btnLayout);
        dia.setFixedSize(300,280);
        dia.exec();
    });


    //删除事件
    QAction * pDelSysAction = ui->DelSys_Act;
    QAction * pDelSubAction = ui->DelMsg_Act;
    QAction * pDelMsgAction = ui->DelData_Act;
    connect(pDelSysAction,&QAction::triggered,
            [&]
    {
        auto SysView = FindViewItemByName("SysView");
        if(nullptr == SysView || SysView->selectedItems().count() == 0) return;

        CreateDelMessageBox("选定的系统将被删除，删除后数据不可恢复！",SYSPANEL);
    });
    connect(pDelSubAction,&QAction::triggered,
            [&]
    {
        auto SubView = FindViewItemByName("MsgView");
        if(nullptr == SubView || SubView->selectedItems().count() == 0) return ;
        CreateDelMessageBox("选定的消息将被删除，删除后数据不可恢复！",SUBPANEL);
    });
    connect(pDelMsgAction,&QAction::triggered,
            [&]
    {
        auto DataInfoView = FindViewItemByName("DataView");
        if(nullptr == DataInfoView || DataInfoView->selectedItems().count() == 0) return;
        CreateDelMessageBox("选定的数据将被删除，删除后数据不可恢复！",SUBDATAPANEL);
    });


    //SVN Function
    QAction * pUpdateAct = ui->Update_Act;
    connect(pUpdateAct,&QAction::triggered,
            [&]
    {
        DoSVNSomeThing(Updatete);
    });
    QAction * pCommitAct = ui->SubCommit_Act;
    connect(pCommitAct,&QAction::triggered,
            [&]
    {

        //https://blog.csdn.net/weixin_39612877/article/details/110980925?utm_term=qt%E8%AF%BB%E5%8F%96%E6%96%87%E4%BB%B6%E7%9A%84%E7%9B%B8%E5%AF%B9%E8%B7%AF%E5%BE%84&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-0-110980925&spm=3001.4430
        DoSVNSomeThing(Commit);
    });
}

void ProtocolEditor::DoSVNSomeThing(int nType)
{

    QString cmd = "";
    QString sFilePath = "";
    switch (nType)
    {
        case Updatete:
        {
            sFilePath =  "./Update.txt";
            break;
        }
        case Commit:
        {
            sFilePath =  "./Commit.txt";
            break;
        }
    }

    if(sFilePath.isEmpty()) return;


    QFile file(sFilePath);
    if(!file.open(QIODevice::ReadOnly))
      return;
    QTextStream inStream(&file);
    inStream.setCodec("UTF-8");

    QStringList sTextData;
    while(!inStream.atEnd())
    {
      sTextData.append(inStream.readLine());
    }
    if(sTextData.empty()) return;

    QStringList args = sTextData[0].split(" ");// /command:commit /path:.\ /closeonend:3
    cmd =args[0];
    args.erase(args.begin());
    auto d = args[1].data();
    //args[1].chop(1);    //转移多了一个字符" 直接去掉算了
    QStringList as;
    as.append("/command:commit");
    as.append("/path:.\"\\");
    as.append("/closeonend:3");

    m_process = new QProcess(this);
    m_process->setProcessChannelMode(QProcess::MergedChannels);
    m_process->start(cmd, args);

    if (!m_process->waitForStarted())
    {
        QMessageBox::critical(this, "错误", "SVN 运行失败:[ "+m_process->errorString()+" ]","确定");
    }
    file.close();
}


void ProtocolEditor::LoadSystemFile(const QString sFilePath,int nSelect)
{
    if(sFilePath.isEmpty() || !QFile::exists(sFilePath))
        return;
    QFile file(sFilePath);
    if(!file.open(QFile::ReadWrite))
        return;

    QDomDocument doc;
    if(!doc.setContent(&file))
    {
        file.close();
        return;
    }
    file.close();

    QTableWidget* SysViewItem = FindViewItemByName( "SysView");
    if(nullptr == SysViewItem)
        exit(1);
    SysViewItem->setRowCount(0);
    SysViewItem->setSortingEnabled(false); //增加item之前关闭排序
    QDomElement root = doc.documentElement();
    if(!root.hasChildNodes())
    {
        //没有系统协议,就把所有显示面板都清空掉
        QTableWidget* SubViewItem = FindViewItemByName( "MsgView");
        if(nullptr != SubViewItem)
        {
            SubViewItem->setSortingEnabled(false);
            SubViewItem->setRowCount(0);
        }
        QTableWidget* DataViewItem = FindViewItemByName("DataView");
        if(nullptr != DataViewItem)
        {
            DataViewItem->setSortingEnabled(false);
            DataViewItem->setRowCount(0);
        }
        QTextEdit *edit = FindDataInfoViewByName("DataInfoView");
        if(nullptr != edit)
        {
            edit->clear();
        }
        return;
    }

    QDomNode node = root.firstChild();
    QVector<SysTmpData> data;
    while(!node.isNull())
    {
        if(node.isElement())
        {
            QDomElement ment = node.toElement();

            SysTmpData insterData;
            insterData.nId = ment.attribute("id").toInt();
            insterData.sData = ment.attribute("name");
            data.push_back(insterData);
            node = node.nextSibling();
        }
    }
    std::sort(data.begin(), data.end(),[](SysTmpData&a, SysTmpData&b)
    {
        return a.nId < b.nId;
    });

    bool bUpdate = false;
    //把缓存的护具排好序后在初始化到面板上
    for(int i = 0; i <data.size();++i)
    {
        INT RowCont;
        RowCont=SysViewItem->rowCount();
        SysViewItem->insertRow(RowCont);
        QTableWidgetItem *item1 = new QTableWidgetItem();
        QTableWidgetItem *item2 = new QTableWidgetItem("[ "+data[i].sData+" ]");
        item1->setData(Qt::DisplayRole,data[i].nId);
        item1->setText(QString::number(data[i].nId));
        if(nullptr == item1 || nullptr == item2 )   exit(1);
        item1->setTextAlignment(Qt::AlignCenter );
        item1->setTextColor(QColor(0,0,255));
        item2->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter  );
        SysViewItem->setItem(RowCont,0,item1);
        SysViewItem->setItem(RowCont,1,item2);

        if(!bUpdate)
        {
            if(nSelect == data[i].nId)
            {
                SysViewItem->selectRow(RowCont);
                bUpdate = !bUpdate;
            }
            if(nSelect == -1)
            {
                SysViewItem->selectRow(0);
                bUpdate = !bUpdate;
            }
            if(bUpdate)
            {
                LoadSubSystemFile(GetSubFilePath(),data[i].nId);
            }
        }
    }

    SysViewItem->setSortingEnabled(true);   //完成后在重新开启排序，避免出现奇怪的问题
    return ;
}

void ProtocolEditor::LoadSubSystemFile(const QString sFilePath,int nSysId,int nSelect,int nType)
{

    if(sFilePath.isEmpty()) return;
    QString sFileName;
    const char FileNameBuff[64] = "%d.xml";
    sFileName.sprintf(FileNameBuff,nSysId);
    QFile subFile(sFilePath+sFileName);
    if(!subFile.exists())
    {
         if(!Probutility:: CreateFile(GetSubFilePath()+QString::number(nSysId)+".xml",FileTag))
        {
            QString errorStr;
            QMessageBox::information(this, "创建文件错误", errorStr+",FileName:<"+QString::number(nSysId)+".xml"+">",QMessageBox::Close , QMessageBox::Close);
            return ;
        }
    }

    if(!subFile.open(QIODevice::ReadOnly))
    {
        return;
    }
    QDomDocument doc;
    INT errorCol;   INT errorLine;QString errorStr;
    if(!doc.setContent(&subFile,true,&errorStr,&errorLine,&errorCol))
    {
        subFile.close();
        qWarning() << errorStr << "line: " << errorLine << "col: " << errorCol;
        QMessageBox::information(this, "打开文件错误", errorStr+",FileName:<"+sFileName+">",QMessageBox::Close , QMessageBox::Close);
        return ;
    }
    subFile.close();

    QDomElement root = doc.documentElement();
    QDomNode node = root.firstChild();
    QTableWidget* SubViewItem = FindViewItemByName( "MsgView");
    if(nullptr == SubViewItem) exit(1);
    SubViewItem->setSortingEnabled(false);
    SubViewItem->setRowCount(0);

    QTableWidget* DataViewItem = FindViewItemByName("DataView");
    if(nullptr != DataViewItem)
    {
        DataViewItem->setSortingEnabled(false);
        DataViewItem->setRowCount(0);
    }
    QTextEdit *edit = FindDataInfoViewByName("DataInfoView");
    if(nullptr != edit)
    {
        edit->clear();
    }

    bool bUpdate = false;
    QDomElement ment;
    bool b_save = false;
    while(!node.isNull())
    {
        if(node.isElement())
        {
            ment = node.toElement();
            //子协议数据解析
            INT nSubId = ment.attribute("id").toInt();
            INT nMsgType = 1;   //这里是为了兼容以前的协议客户端类型没有type这个标记
            if(ment.hasAttribute("type"))
            {
                nMsgType = ment.attribute("type").toInt();
                b_save = true;
            }else
            {
                ment.setAttribute("type",nMsgType);
            }
            INT RowCont;
            RowCont=SubViewItem->rowCount();
            SubViewItem->insertRow(RowCont);

            //插入元素
            QTableWidgetItem *item1 = new QTableWidgetItem(nMsgType);
            QTableWidgetItem *item2 = new QTableWidgetItem(ment.attribute("name"));
            QTableWidgetItem *item3 = new QTableWidgetItem(Probutility::GetSystemType(static_cast<eSystemType>(nMsgType)));
            item1->setData(Qt::DisplayRole,nSubId);
            item1->setTextAlignment(Qt::AlignCenter);
            item2->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );
            item3->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter);

            if(nMsgType == Server)
            {
                const QColor color = QColor(252,222,156);
                item3->setBackgroundColor(color);
                item2->setTextColor(QColor(0,0,139));
                item1->setTextColor(QColor(0,0,139));
                item3->setTextColor(QColor(0,0,139));
            }

            SubViewItem->setItem(RowCont,0,item1);
            SubViewItem->setItem(RowCont,1,item2);
            SubViewItem->setItem(RowCont,2,item3);
            if(!bUpdate)
            {
                if(nSelect == -1)
                {
                    SubViewItem->selectRow(0);
                    bUpdate = true;
                }else if(nMsgType == nType && nSelect == nSubId)
                {
                    SubViewItem->selectRow(RowCont);
                    bUpdate = true;
                }
                if(bUpdate)
                {
                    LoadSubSysData(ment.elementsByTagName("Data"));
                }

            }
            node = node.nextSibling();
        }
    }
    SubViewItem->setSortingEnabled(true);
    if(b_save)
    {

        QFile file(sFilePath+sFileName);
        if(!file.open(QFile::WriteOnly|QFile::Truncate))
            return;
        QTextStream out_stream(&file);
        doc.save(out_stream,4); //缩进4格
        file.close();
    }
    return ;
}

void ProtocolEditor::LoadSubSysData(const QDomNodeList list)
{
    QTableWidget* DataView = FindViewItemByName( "DataView");
    if(nullptr == DataView) exit(1);
    DataView->setRowCount(0);
    QTextEdit *edit = FindDataInfoViewByName("DataInfoView");
    if(nullptr != edit)
    {
        edit->clear();
    }
    //遍历子协议下的数据信息
    for(INT i=0;i<list.count();i++) //遍历子元素
    {
        QDomNode SubNode=list.at(i);
        if(SubNode.isElement())
        {
            QDomElement subMent = SubNode.toElement();
            QDomNode Node=subMent.firstChild();

            INT RowCont;
            RowCont=DataView->rowCount();
            DataView->insertRow(RowCont);

            INT nType = subMent.attribute("type").toInt();
            //插入元素
            QString sType = Probutility::GetDataInfoType(static_cast<PROTOCOLDATATYPE>(nType));

            QTableWidgetItem *item1 = new QTableWidgetItem(sType,nType);
            QTableWidgetItem *item2 = new QTableWidgetItem(subMent.attribute("name"));

            item1->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );
            item1->setTextColor(QColor(30,144,255));
            item2->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );

            DataView->setItem(RowCont,0,item1);
            DataView->setItem(RowCont,1,item2);
        }
    }
}

QTableWidget* ProtocolEditor::FindViewItemByName(const QString sName)
{
    if(sName.isEmpty()) return nullptr;

    QList<QTableWidget*> ViewItem =  ui->SysSplitter->findChildren<QTableWidget*>();
    if(ViewItem.isEmpty()) return  nullptr;

    for(auto iter = ViewItem.begin();iter != ViewItem.end();++iter)
    {
        if((*iter)->objectName() == sName)
        {
            return *iter;
        }
    }
    return nullptr;
}

QTextEdit *ProtocolEditor::FindDataInfoViewByName(const QString sName)
{
    QList<QTextEdit*> ViewItem =  ui->SysSplitter->findChildren<QTextEdit*>();
    if(ViewItem.isEmpty()) return nullptr;
    for(auto iter = ViewItem.begin();iter != ViewItem.end();++iter)
    {
        if((*iter)->objectName() == sName)
        {
            return *iter;
        }
    }
    return nullptr;
}

QDomElement ProtocolEditor::FindSubElementNode(int nSysId)
{
    QDomElement root;

    QString sFileName;
    const char FileNameBuff[32] = "%d.xml";
    sFileName.sprintf(FileNameBuff,nSysId);
    const QString sSubFilePaht = QCoreApplication::applicationDirPath()+"/Systems/"+sFileName;

    QFile subFile(sSubFilePaht);
    if(!subFile.open(QIODevice::ReadWrite))
    {
        return root;
    }

    QDomDocument doc;
    INT errorCol;
    INT errorLine;
    QString errorStr;
    if(!doc.setContent(&subFile,true,&errorStr,&errorLine,&errorCol))
    {
        subFile.close();
        qWarning() << errorStr << "line: " << errorLine << "col: " << errorCol;
        QMessageBox::information(this, "打卡文件错误", errorStr+",FileName:<"+sFileName+"> Line:"+QString::number(errorLine),
                                 QMessageBox::Close , QMessageBox::Close);
        return root;
    }
    subFile.close();

    return  doc.documentElement();
}

int ProtocolEditor::GetCurSelectSysItemId()
{
    auto SysView = FindViewItemByName("SysView");
    if(nullptr == SysView) return -1;
    auto pSysItems = SysView->selectedItems();
    if(pSysItems.isEmpty()) return -1;
    int nSysId = pSysItems.at(0)->data(Qt::DisplayRole).toInt();
    return nSysId;
}

int ProtocolEditor::GetCurSelectSysSubItemId()
{
    auto SubView = FindViewItemByName("MsgView");
    if(nullptr == SubView) return -1;
    auto pSubItems = SubView->selectedItems();
    if(pSubItems.isEmpty()) return -1;
    int nSubId = pSubItems.at(0)->data(Qt::DisplayRole).toInt();
    return nSubId;
}

QTableWidgetItem *ProtocolEditor::GetCurSelectSysItem()
{
    auto SubView = FindViewItemByName("SysView");
    if(nullptr == SubView) return  nullptr;

    auto pSubItems = SubView->selectedItems();
    if(pSubItems.isEmpty()) return nullptr;

    return pSubItems.at(0);
}

QTableWidgetItem* ProtocolEditor::GetCurSelectSysSubItem()
{
    auto SubView = FindViewItemByName("MsgView");
    if(nullptr == SubView) return  nullptr;

    auto pSubItems = SubView->selectedItems();
    if(pSubItems.isEmpty()) return nullptr;

    return pSubItems.at(0);
}

QTableWidgetItem* ProtocolEditor::GetCurSelectDatafoItem()
{
    auto DateInfoView = FindViewItemByName("DataView");
    if(nullptr == DateInfoView) return  nullptr;

    auto pDataItems = DateInfoView->selectedItems();
    if(pDataItems.isEmpty()) return nullptr;

    return pDataItems.at(0);
}

bool ProtocolEditor::eventFilter(QObject *obj, QEvent *event)
{
    auto SysView = FindViewItemByName("SysView");
    auto SubView = FindViewItemByName("MsgView");
    auto DataView = FindViewItemByName("DataView");
    if (obj == SysView->viewport() || obj == SubView->viewport() || obj == DataView->viewport())
    {
        if (event->type() == QEvent::MouseButtonPress  || event->type() == QEvent::MouseButtonRelease  ||event->type() ==  QEvent::MouseButtonDblClick )
        {
            QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent *>(event);
            if(mouseEvent->buttons()&Qt::RightButton)
            {
                return  true;
            }
        }else  if(event->type()==QEvent::MouseMove)
        {
            return  true;
        }
    }
    return QMainWindow::eventFilter(obj,event);
}

void ProtocolEditor::CreateDelMessageBox(const QString sTip, const PanelType eType)
{
    QMessageBox meg(QMessageBox::Question, "提示",sTip);
    meg.setIcon(QMessageBox::Warning);
    meg.setWindowIcon(QIcon(":/Icon/Del.png"));
    QPushButton *okBtn= meg.addButton(tr("确定"), QMessageBox::AcceptRole);
    meg.addButton(tr("取消"),QMessageBox::RejectRole);
    meg.exec();

    int nSysId = GetCurSelectSysItemId();
    int nSubId = GetCurSelectSysSubItemId();
    if(nSysId < 0 ) return;
    if(reinterpret_cast<QPushButton*>(meg.clickedButton() )== okBtn)
    {

        switch (static_cast<int>(eType))
        {
        case SYSPANEL:
        {

            if(!QFile::exists(GetSysFilePath()))
                return;
            //删除系统协议并把子协议同时删掉
            QFile file(GetSysFilePath());
            if(!file.open(QFile::ReadOnly))
                return;

            QDomDocument doc;
            if(!doc.setContent(&file))
            {
                file.close();
                return;
            }
            file.close();

            QDomElement root=doc.documentElement();
            QDomNodeList list=doc.elementsByTagName("System");
            for(int i=0;i<list.count();i++)
            {
                QDomElement e=list.at(i).toElement();
                if(e.attribute("id").toInt()==nSysId)
                {
                    root.removeChild(list.at(i));
                    break;
                }
            }
            if(!file.open(QFile::WriteOnly|QFile::Truncate))
                return;
            QTextStream out_stream(&file);
            doc.save(out_stream,4); //缩进4格
            file.close();

            QFile SysFile(GetSubFilePath()+QString::number(nSysId)+".xml");
            if(SysFile.exists())
                SysFile.remove();
            LoadSystemFile(GetSysFilePath());
            break;
        }
        case SUBPANEL:
        {
            if(nSubId < 0) return;
            const auto& pSubItem = GetCurSelectSysSubItem();
            if (nullptr == pSubItem) return ;
            int nType =  pSubItem->type();
            QString sub_path = GetSubFilePath()+QString::number(nSysId)+".xml";
            if(!QFile::exists(sub_path))
                return;

            //删除子协议及包含数据
            QFile file(sub_path);
            if(!file.open(QFile::ReadOnly)) return;
            QDomDocument doc;
            if(!doc.setContent(&file))
            {
                file.close();
                return;
            }
            file.close();
            QDomElement root=doc.documentElement();
            QDomNodeList list=doc.elementsByTagName(FileSubTag);
            for(int i=0;i<list.count();i++)
            {
                QDomElement e=list.at(i).toElement();
                if(e.attribute("id").toInt()==nSubId &&e.attribute("type").toInt() == nType )
                {
                    root.removeChild(list.at(i));
                    break;
                }
            }
            if(!file.open(QFile::WriteOnly|QFile::Truncate))
                return;
            QTextStream out_stream(&file);
            doc.save(out_stream,4); //缩进4格
            file.close();
            LoadSubSystemFile(GetSubFilePath(),nSysId);
            break;
        }
        case SUBDATAPANEL:
        {
            //删除数据即可
            const auto& pSubItem = GetCurSelectSysSubItem();
            const auto& pSubView =FindViewItemByName("MsgView");
            const auto& pDataInfoItem = GetCurSelectDatafoItem();
            if(nSubId < 0) return;
            if (nullptr == pSubItem || nullptr == pDataInfoItem || nullptr == pSubView)
                return ;

            int nType =  pSubItem->type();
            int nDataType =pDataInfoItem->type();

            QString sub_path = GetSubFilePath()+QString::number(nSysId)+".xml";
            if(!QFile::exists(sub_path))
                return;
            //删除子协议及包含数据
            QFile file(sub_path);
            if(!file.open(QFile::ReadOnly)) return;

            QDomDocument doc;
            if(!doc.setContent(&file))
            {
                file.close();
                return;
            }
            file.close();

            QDomElement root=doc.documentElement();
            QDomNodeList list=doc.elementsByTagName(FileSubTag);

            for(int i=0;i<list.count();i++)
            {
                QDomElement e=list.at(i).toElement();
                if(e.attribute("id").toInt()==nSubId &&  e.attribute("type").toInt() == nType )
                {
                    const auto& childE = e.elementsByTagName("Data");
                    for(int j = 0; j < childE.count();++j)
                    {
                        QDomElement childe = childE.at(j).toElement();
                        auto DateInfoView = FindViewItemByName("DataView");
                        if(nullptr == DateInfoView) return ;
                        auto pDataItems = DateInfoView->selectedItems();
                        if(pDataItems.isEmpty()) return ;
                        if(childe.attribute("type").toInt() == nDataType && childe.attribute("name").compare( pDataItems.at(1)->text(),Qt::CaseSensitive) == 0 )
                        {
                            e.removeChild(childE.at(j));
                            break;
                        }
                    }
                }
            }

            if(!file.open(QFile::WriteOnly|QFile::Truncate))return;
            QTextStream out_stream(&file);
            doc.save(out_stream,4); //缩进4格
            file.close();
            {
                QDomElement rootXml = FindSubElementNode(nSysId);
                QDomNode node = rootXml.firstChild();
                while(!node.isNull())
                {
                    if(node.isElement())
                    {
                        QDomElement ment = node.toElement();
                        if(ment.attribute("id").toInt() == nSubId && ment.attribute("type").toInt() == nType)
                        {
                            LoadSubSysData(ment.elementsByTagName("Data"));
                            break;
                        }
                        node = node.nextSibling();
                    }
                }
            }
            break;
        }
        }

    }
}

void ProtocolEditor::sortSubTableByCol(int nCol)
{
    auto SysView = FindViewItemByName("MsgView");
    if(nullptr == SysView) return;
    SysView->sortItems(nCol,Qt::AscendingOrder);
}

void ProtocolEditor::onCurrentLineHighLight()
{
    QTextEdit *edit = FindDataInfoViewByName("DataInfoView");
    QList<QTextEdit::ExtraSelection> extraSelection;
    QTextEdit::ExtraSelection selection;
    QColor lineColor = QColor(Qt::yellow).lighter(85);
    selection.format.setBackground(lineColor);
    selection.format.setProperty(QTextFormat::FullWidthSelection,true);
    selection.cursor = edit->textCursor();
    selection.cursor.clearSelection();
    //将刚设置的 selection追加到链表当中
    extraSelection.append(selection);
    edit->setExtraSelections(extraSelection);
}
void ProtocolEditor::sortSysTableByCol(int nCol)
{
    auto SysView = FindViewItemByName("SysView");
    if(nullptr == SysView) return;
    SysView->sortItems(nCol,Qt::AscendingOrder);
}

void ProtocolEditor::on_RecvFindRes(int nSysId, int nSubId,int nSubType)
{
    m_FindEditor.close();

    auto SysView = FindViewItemByName("SysView");
    if(nullptr == SysView) return ;
    int nRows = SysView->rowCount();
    if(nRows <= 0) return;

    for(int i = 0; i< nRows;++i)
    {
        auto pItem =SysView->item(i,0);
        if(nullptr ==pItem) continue;
        if(nSysId == pItem->data(Qt::DisplayRole).toInt())
        {
            SysView->selectRow(i);
            //更新系统
            on_SysView_cellClicked(i,0);
            break;
        }
    }

    auto SubView = FindViewItemByName("MsgView");
    if(nullptr == SubView) return ;
    nRows = SubView->rowCount();
    if(nRows <= 0) return;

    for(int i = 0; i< nRows;++i)
    {
        auto pItem =SubView->item(i,0);
        if(nullptr ==pItem) continue;
        if(nSubId == pItem->data(Qt::DisplayRole).toInt() && nSubType == pItem->type())
        {
            SubView->selectRow(i);
            //更新子系统数据
            on_MsgView_cellClicked(i,0);
            break;
        }
    }
}

void ProtocolEditor::on_DataView_cellClicked(int row, int )
{
    auto DataInfoView = FindDataInfoViewByName("DataInfoView");
    if(nullptr == DataInfoView) return;
    DataInfoView->clear();

    //获取子系统id
    auto SubView = FindViewItemByName("MsgView");
    if(nullptr == SubView) return;
    auto pSubItems = SubView->selectedItems();
    if(pSubItems.isEmpty()) return;

    QTableWidget* DataView = FindViewItemByName( "DataView");
    if(nullptr == DataView) return;
    auto pItems = DataView->item(row,0);
    if(nullptr == pItems)return;

    int DataType  = pItems->type();
    int nSysId = GetCurSelectSysItemId();

    int nSubId = pSubItems.at(0)->data(Qt::DisplayRole).toInt();
    int nType = pSubItems.at(0)->type();

    QDomElement root = FindSubElementNode(nSysId);
    QDomNode node = root.firstChild();

    while(!node.isNull())
    {
        if(node.isElement())
        {
            QDomElement ment = node.toElement();
            if(ment.attribute("id").toInt() == nSubId
                    && ment.attribute("type").toInt() == nType)       //比较子系统
            {
                //遍历子协议下的数据信息
                for(INT i=0;i<ment.childNodes().count();i++) //遍历子元素
                {
                    QDomNode SubNode=ment.childNodes().at(i);
                    if(SubNode.isElement())
                    {
                        QDomElement subMent = SubNode.toElement();
                        int nType = subMent.attribute("type").toInt();
                        if(nType == DataType  &&  subMent.attribute("name").compare(DataView->item(row,1)->text(),Qt::CaseSensitive) == 0)
                        {
                            DataInfoView->setText(subMent.toElement().text());
                        }
                    }
                }
            }
            node = node.nextSibling();
        }
    }
}

void ProtocolEditor::on_SysView_cellClicked(int row, int )
{
    auto SysView = FindViewItemByName("SysView");
    if(nullptr == SysView) return;

    auto SubView = FindViewItemByName("MsgView");
    if(nullptr == SubView) return;
    SubView->setRowCount(0);

    auto DataView = FindViewItemByName("DataView");
    if(nullptr == DataView) return;
    DataView->setRowCount(0);

    auto DataInfoView = FindDataInfoViewByName("DataInfoView");
    if(nullptr == DataInfoView) return;
    DataInfoView->clear();

    auto pItems = SysView->item(row,0);
    if(nullptr == pItems)return;

    int nSysId = pItems->data(Qt::DisplayRole).toInt();

    LoadSubSystemFile(GetSubFilePath(),nSysId);
}

void ProtocolEditor::on_MsgView_cellClicked(int row, int )
{
    int nSysId = GetCurSelectSysItemId();

    auto DataView = FindViewItemByName("DataView");     //清空面板
    if(nullptr == DataView) return;
    DataView->setRowCount(0);

    //获取子系统id
    auto SubView = FindViewItemByName("MsgView");
    if(nullptr == SubView) return ;
    auto pSubItems = SubView->item(row,0);
    if(nullptr == pSubItems)return ;

    auto DataInfoView = FindDataInfoViewByName("DataInfoView");
    if(nullptr == DataInfoView) return;
    DataInfoView->clear();

    int nSubId = pSubItems->data(Qt::DisplayRole).toInt();  //Id && Type
    int nType = pSubItems->type();           //server or client (这里做下兼容，旧的协议文件客户端没有type这个标记)
    QDomElement root = FindSubElementNode(nSysId);
    QDomNode node = root.firstChild();
    while(!node.isNull())
    {
        if(node.isElement())
        {
            QDomElement ment = node.toElement();
            int attr_type = 1;
            if(ment.hasAttribute("type"))
            {
                attr_type = ment.attribute("type").toInt();
            }
            if(ment.attribute("id").toInt() == nSubId && attr_type == nType)
            {
                LoadSubSysData(ment.elementsByTagName("Data"));
                break;
            }
            node = node.nextSibling();
        }
    }
}

void ProtocolEditor::on_SysView_itemDoubleClicked(QTableWidgetItem *item)
{
    //是否有选中系统，没有不可操作
    auto DataView = FindViewItemByName("SysView");
    if(nullptr == DataView || DataView->selectedItems().count() == 0) return;

    auto pItem1 = DataView->selectedItems().at(0);
    auto pItem2 = DataView->selectedItems().at(1);
    if(nullptr == pItem1 || nullptr == pItem2) return;

    int nId      = pItem1->data(Qt::DisplayRole).toInt();
    QString sMsg = pItem2->text();
    sMsg = sMsg.mid(2,sMsg.length()-4);
    if(nullptr == item) return;
    m_SysEditor.InitSysProtocolEditor(EDIT_DATA,nId,sMsg);
    m_SysEditor.setWindowModality(Qt::ApplicationModal);
    m_SysEditor.show();
}

void ProtocolEditor::on_MsgView_itemDoubleClicked(QTableWidgetItem *item)
{
    auto SubView = FindViewItemByName("MsgView");
    if(nullptr == SubView || SubView->selectedItems().count() == 0) return ;

    int nId = SubView->selectedItems().at(0)->data(Qt::DisplayRole).toInt();
    int nMsgType = SubView->selectedItems().at(0)->type();
    QString sMsg = SubView->selectedItems().at(1)->text();

    if(nullptr == item) return;
    m_SysSubEditor.InitSysSubProtocolEditor(EDIT_DATA,nId,nMsgType,sMsg);
    m_SysSubEditor.setWindowModality(Qt::ApplicationModal);
    m_SysSubEditor.show();
}

void ProtocolEditor::on_DataView_itemDoubleClicked(QTableWidgetItem *item)
{
    auto SubView = FindViewItemByName("MsgView");
    if(nullptr == SubView || SubView->selectedItems().count() == 0) return ;

    auto DataView = FindViewItemByName("DataView");
    if(nullptr == DataView || DataView->selectedItems().count() == 0) return ;

    int nType = DataView->selectedItems().at(0)->type();
    QString sInfoData = DataView->selectedItems().at(1)->text();
    auto DataInfoView = FindDataInfoViewByName("DataInfoView");
    if(nullptr == DataInfoView) return;
    QString sMsg = DataInfoView->toPlainText();

    m_DataOldData.nType =nType;
    m_DataOldData.sData = sInfoData;
    m_DataOldData.sInfo =sMsg;
    if(nullptr == item) return;
    m_SubDataEditor.InitSubDataProtocolEditor(EDIT_DATA,nType,sInfoData,sMsg);
    m_SubDataEditor.setWindowModality(Qt::ApplicationModal);
    m_SubDataEditor.show();
}

void ProtocolEditor::on_CreateSysProtocolSlot(int nSysId, const QString sData)
{
    if(nSysId < 0 || sData.isEmpty()) return;

    if(!QFile::exists(GetSysFilePath()))
    {
        if(!Probutility::CreateFile(GetSysFilePath()))
        {
            QString errorStr;
            qWarning() << errorStr;
            QMessageBox::information(this, "创建文件错误", errorStr+",FileName:<Systems.xml>",QMessageBox::Close , QMessageBox::Close);
            return ;
        }
    }
    QFile sysFile(GetSysFilePath());
    if(!sysFile.open(QFile::ReadWrite)) return;

    QDomDocument doc;
    int errorCol;   int errorLine;QString errorStr;
    if(!doc.setContent(&sysFile,true,&errorStr,&errorLine,&errorCol))
    {
        sysFile.close();
        qWarning() << errorStr << "line: " << errorLine << "col: " << errorCol;
        QMessageBox::information(this, "打开文件错误", errorStr+",FileName:<Systems.xml>",QMessageBox::Close , QMessageBox::Close);
        return ;
    }

    sysFile.close();
    QDomElement root = doc.documentElement();
    QDomNode node = root.firstChild();
    while(!node.isNull())
    {
        if(node.isElement())
        {
            QDomElement ment = node.toElement();
            if(ment.attribute("id").toInt() == nSysId)
            {
                QMessageBox::critical(this, "错误", "当前已存在对应的系统Id:[ "+QString::number(nSysId)+" ]","确定");
                return;
            }
            node = node.nextSibling();
        }
    }
    QDomElement System = doc.createElement("System");
    System.setAttribute("id",nSysId);
    System.setAttribute("name",sData);
    root.appendChild(System);

    if(!sysFile.open(QFile::WriteOnly|QFile::Truncate)) //先读进来，再重写，如果不用truncate就是在后面追加内容，就无效了
        return;

    //输出到文件
    QTextStream out_stream(&sysFile);
    doc.save(out_stream,4); //缩进4格
    sysFile.close();

    //创建子系统文件
    if(!Probutility:: CreateFile(GetSubFilePath()+QString::number(nSysId)+".xml",FileTag))
    {
        QString errorStr;
        qWarning() << errorStr;
        QMessageBox::information(this, "创建文件错误", errorStr+",FileName:<"+QString::number(nSysId)+".xml"+">",QMessageBox::Close , QMessageBox::Close);
        return ;
    }
    LoadSystemFile(GetSysFilePath(),nSysId);
}

//这里有一个问题，如果修改的id是不存在的id，那么是直接创建一个还是把当前这个协议包括下面的自协议转移过去？ 待考虑
void ProtocolEditor::on_EditorSysProtocolSlot(int nSysId, const QString sData,int nOldSysId)
{
    if(nSysId < 0 || sData.isEmpty()) return;
    auto pSysView = FindViewItemByName("SysView");
    if(nullptr == pSysView) return;
    int nCurSelectRow = pSysView->currentRow();

    if(!QFile::exists(GetSysFilePath()))
        return;
    QFile file(GetSysFilePath());
    if(!file.open(QFile::ReadOnly)) return;

    QDomDocument doc;
    if(!doc.setContent(&file))
    {
        file.close();
        return;
    }
    file.close();

    QDomElement root=doc.documentElement();
    QDomNode node = root.firstChild();
    while(!node.isNull())
    {
        if(node.isElement())
        {
            QDomElement ment = node.toElement();
            if(ment.attribute("id").toInt() == nSysId)
            {
                if( nSysId != nOldSysId && nOldSysId >= 0)//修改了协议id，并且这个修改的id已经存在。就直接不让这个操作
                {
                    QMessageBox::critical(this, "错误", "当前已存在对应的系统Id:[ "+QString::number(nSysId)+" ]","确定");
                    return;
                }
                ment.setAttribute("name",sData);
                if(!file.open(QFile::WriteOnly|QFile::Truncate)) return;
                QTextStream out_stream(&file);
                doc.save(out_stream,4); //缩进4格
                file.close();
                LoadSystemFile(GetSysFilePath());
                pSysView->selectRow(nCurSelectRow);
                on_SysView_cellClicked(nCurSelectRow,0);
                return;
            }
            node = node.nextSibling();
        }
    }
    on_CreateSysProtocolSlot(nSysId,sData);
}

void ProtocolEditor::on_CreateSysSubProtocolSlot(int nSubId, const QString sData, int nType)
{
    int nSysId =GetCurSelectSysItemId();
    if(nSysId < 0 || nSubId < 0 || sData.isEmpty()) return;

    QFile subFile(GetSubFilePath()+QString::number(nSysId)+".xml");

    if(!subFile.exists())
    {
        if(!Probutility:: CreateFile(GetSubFilePath()+QString::number(nSysId)+".xml",FileTag))
        {
            QString errorStr;
            QMessageBox::information(this, "创建文件错误", errorStr+",FileName:<"+QString::number(nSysId)+".xml"+">",QMessageBox::Close , QMessageBox::Close);
            return ;
        }
    }

    if(!subFile.open(QFile::ReadWrite))
        return;

    QDomDocument doc;
    int errorCol;   int errorLine;QString errorStr;
    if(!doc.setContent(&subFile,true,&errorStr,&errorLine,&errorCol))
    {
        subFile.close();
        qWarning() << errorStr << "line: " << errorLine << "col: " << errorCol;
        QMessageBox::information(this, "打开文件错误", errorStr+",FileName:<"+QString::number(nSysId)+".xml"+">",QMessageBox::Close , QMessageBox::Close);
        return ;
    }
    subFile.close();

    QDomElement root = doc.documentElement();
    QDomNode node = root.firstChild();

    while(!node.isNull())
    {
        if(node.isElement())
        {
            QDomElement ment = node.toElement();
            if(ment.attribute("id").toInt() == nSubId && ment.attribute("type").toInt()==nType)
            {
                QMessageBox::critical(this, "错误", "当前已存在对应的协议Id:[ "+QString::number(nSubId)+" ], 类型：<"+Probutility::GetSystemType(static_cast<eSystemType>(nType))+">","确定");
                return;
            }
            node = node.nextSibling();
        }
    }

    root = doc.documentElement();
    QDomElement SubElem = doc.createElement(FileSubTag);
    SubElem.setAttribute("name",sData);
    SubElem.setAttribute("type",nType);
    SubElem.setAttribute("id",nSubId);
    root.appendChild(SubElem);

    if(!subFile.open(QFile::WriteOnly|QFile::Truncate)) //先读进来，再重写，如果不用truncate就是在后面追加内容，就无效了
        return;

    //输出到文件
    QTextStream out_stream(&subFile);
    doc.save(out_stream,4); //缩进4格
    subFile.close();

    LoadSubSystemFile(GetSubFilePath(),nSysId,nSubId,nType);
}

void ProtocolEditor::on_EditorSysSubProtocolSlot(int nSubId, const QString sData, int nType, int nOldSysId)
{
    int nSysId =GetCurSelectSysItemId();
    if(nSysId < 0) return;
    auto pSubView = FindViewItemByName("MsgView");
    if(nullptr == pSubView) return;

    int nCurSelectRow =pSubView->currentRow();


    if(!QFile::exists(GetSubFilePath()+QString::number(nSysId)+".xml"))
        return;

    QFile file(GetSubFilePath()+QString::number(nSysId)+".xml");
    if(!file.open(QFile::ReadOnly)) return;

    QDomDocument doc;
    if(!doc.setContent(&file))
    {
        file.close();
        return;
    }
    file.close();

    QDomElement root=doc.documentElement();

    QDomNode node = root.firstChild();

    while(!node.isNull())
    {
        if(node.isElement())
        {
            QDomElement ment = node.toElement();
            if(ment.attribute("id").toInt() == nSubId && ment.attribute("type").toInt()==nType)
            {
                if( nSubId != nOldSysId && nOldSysId >= 0)//修改了协议id，并且这个修改的id已经存在。就直接不让这个操作
                {
                    QMessageBox::critical(this, "错误", "当前已存在对应的协议Id:[ "+QString::number(nSubId)+" ], 类型：<"+Probutility::GetSystemType(static_cast<eSystemType>(nType))+">","确定");
                    return;
                }
                ment.setAttribute("name",sData);
                if(!file.open(QFile::WriteOnly|QFile::Truncate)) return;
                QTextStream out_stream(&file);
                doc.save(out_stream,4); //缩进4格
                file.close();
                auto pSysView = FindViewItemByName("SysView");
                if(nullptr == pSysView) return;
                LoadSubSystemFile(GetSubFilePath(),nSysId);
                pSubView->selectRow(nCurSelectRow);                    //更新一下选择的item
                on_MsgView_cellClicked(nCurSelectRow,0);
                return;

            }
            node = node.nextSibling();
        }
    }
    //如果当前不存在就新建一个
    on_CreateSysSubProtocolSlot(nSubId,sData,nType);
}

void ProtocolEditor::on_CreateSubDataProtocolSlot(int nType,const QString sData,const QString sDataInfo)
{
    int nSysId = GetCurSelectSysItemId();
    const auto& pSubItem = GetCurSelectSysSubItem();
    if(nSysId < 0 || nullptr == pSubItem) return;

    int nSubId =pSubItem->data(Qt::DisplayRole).toInt();
    int nSubType =pSubItem->type();
    if(!QFile::exists(GetSubFilePath()+QString::number(nSysId)+".xml"))
        return;
    QFile file(GetSubFilePath()+QString::number(nSysId)+".xml");

    if(!file.exists())
    {
        QString errorStr;
        QMessageBox::information(this, "打开文件错误", errorStr+",FileName:<"+QString::number(nSysId)+".xml"+">",QMessageBox::Close , QMessageBox::Close);
        return;
    }

    if(!file.open(QFile::ReadWrite))
        return;

    QDomDocument doc;
    int errorCol;   int errorLine;QString errorStr;
    if(!doc.setContent(&file,true,&errorStr,&errorLine,&errorCol))
    {
        file.close();
        QMessageBox::information(this, "打开文件错误", errorStr+",FileName:<"+QString::number(nSysId)+".xml"+">",QMessageBox::Close , QMessageBox::Close);
        return ;
    }
    file.close();

    QDomElement root=doc.documentElement();
    QDomNodeList list=doc.elementsByTagName(FileSubTag);

    //遍历查找子系统
    for(int i=0;i<list.count();i++)
    {
        QDomElement e=list.at(i).toElement();
        if(e.attribute("id").toInt()==nSubId &&e.attribute("type").toInt() == nSubType )
        {
            QDomElement dataE = doc.createElement("Data");
            dataE.setAttribute("name",sData);
            dataE.setAttribute("type",nType);
            QDomElement InfoE = doc.createElement("CType");
            QDomCDATASection cData = doc.createCDATASection(sDataInfo);
            InfoE.appendChild(cData);
            dataE.appendChild(InfoE);
            e.appendChild(dataE);
            break;
        }
    }
    if(!file.open(QFile::WriteOnly|QFile::Truncate)) //先读进来，再重写，如果不用truncate就是在后面追加内容，就无效了
        return;

    //输出到文件
    QTextStream out_stream(&file);
    doc.save(out_stream,4); //缩进4格
    file.close();

    const auto& pSubView =FindViewItemByName("MsgView");
    if(nullptr == pSubView) return;
    on_MsgView_cellClicked(pSubView->currentRow(),0);
}

void ProtocolEditor::on_EditorSubDataProtocolSlot(int nType,const QString sData,const QString sDataInfo)
{
    int nSysId =GetCurSelectSysItemId();
    if(nSysId < 0) return;

    const auto& pSubItem =GetCurSelectSysSubItem();
    if(nullptr == pSubItem) return;
    int nSubId =pSubItem->data(Qt::DisplayRole).toInt();
    int nSubType =pSubItem->type();

    const auto& pDataView =FindViewItemByName("DataView");
    if(nullptr == pDataView) return;

    int nCueSelectRow = pDataView->currentRow();

    if(!QFile::exists(GetSubFilePath()+QString::number(nSysId)+".xml"))
        return;
    QFile file(GetSubFilePath()+QString::number(nSysId)+".xml");

    if(!file.exists())
    {
        QString errorStr;
        QMessageBox::information(this, "打开文件错误", errorStr+",FileName:<"+QString::number(nSysId)+".xml"+">",QMessageBox::Close , QMessageBox::Close);
        return;
    }

    if(!file.open(QFile::ReadWrite))
        return;

    QDomDocument doc;
    int errorCol;   int errorLine;QString errorStr;
    if(!doc.setContent(&file,true,&errorStr,&errorLine,&errorCol))
    {
        file.close();
        QMessageBox::information(this, "打开文件错误", errorStr+",FileName:<"+QString::number(nSysId)+".xml"+">",QMessageBox::Close , QMessageBox::Close);
        return ;
    }
    file.close();

    QDomElement root=doc.documentElement();
    QDomNodeList list=doc.elementsByTagName(FileSubTag);

    //遍历查找子系统
    for(int i=0;i<list.count();i++)
    {
        QDomElement e=list.at(i).toElement();
        if(e.attribute("id").toInt()==nSubId &&e.attribute("type").toInt() == nSubType )
        {
            QDomNodeList childE =e.elementsByTagName("Data");
            for(int j = 0; j < childE.count();++j)
            {
                QDomElement childe = childE.at(j).toElement();
                if(childe.attribute("type").toInt() == m_DataOldData.nType
                        && childe.attribute("name").compare(m_DataOldData.sData,Qt::CaseSensitive) == 0 )
                {
                    childe.setAttribute("name",sData);
                    childe.setAttribute("type",nType);
                    QDomNodeList InfoE =childe.elementsByTagName("CType");
                    childe.removeChild(InfoE.at(0));
                    auto cType = doc.createElement("CType");
                    QDomCDATASection cData = doc.createCDATASection(sDataInfo);
                    cType.appendChild(cData);
                    childe.appendChild(cType);
                    break;
                }
            }
        }
    }
    if(!file.open(QFile::WriteOnly|QFile::Truncate)) //先读进来，再重写，如果不用truncate就是在后面追加内容，就无效了
        return;

    //输出到文件
    QTextStream out_stream(&file);
    doc.save(out_stream,4); //缩进4格
    file.close();

    const auto& pSubView =FindViewItemByName("MsgView");
    if(nullptr == pSubView) return;
    on_MsgView_cellClicked(pSubView->currentRow(),0);

    pDataView->selectRow(nCueSelectRow);
    on_DataView_cellClicked(nCueSelectRow,0);
}

void ProtocolEditor::on_SysView_cellPressed(int row, int column)
{
    on_SysView_cellClicked(row,column);
}

void ProtocolEditor::on_MsgView_cellPressed(int row, int column)
{
    on_MsgView_cellClicked(row,column);
}

void ProtocolEditor::on_DataView_cellPressed(int row, int column)
{
    on_DataView_cellClicked(row,column);
}

void ProtocolEditor::on_upBtn_clicked()
{
    auto SubView = FindViewItemByName("DataView");
    if(nullptr == SubView || SubView->rowCount() < 1) return;

    auto pSubItems = SubView->selectedItems();
    if(pSubItems.isEmpty())  return;

    auto pItem = pSubItems.at(0);
    if(nullptr == pItem)return;

    int nNowRow = pItem->row();
    int nMoveRow = nNowRow - 1;
    if(nMoveRow < 0)
        return;

    //选中的items
    auto pNowItem1 = SubView->item(nNowRow,0);
    auto pNowItem2 = SubView->item(nNowRow,1);
    if(nullptr == pNowItem1 || nullptr == pNowItem2)
        return;

    //目标的items
    auto pMoveItem1 = SubView->item(nMoveRow,0);
    auto pMoveItem2 = SubView->item(nMoveRow,1);
    if(nullptr == pMoveItem1 || nullptr == pMoveItem2)
        return;

    int nType1 = pMoveItem1->type();
    QString sType1 = Probutility::GetDataInfoType(static_cast<PROTOCOLDATATYPE>(nType1));
    QString sMsg1 = pMoveItem2->data(0).toString();
    QTableWidgetItem *down1 = new QTableWidgetItem(sType1,nType1);
    QTableWidgetItem *down2 = new QTableWidgetItem(sMsg1);
    down1->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );
    down1->setTextColor(QColor(30,144,255));
    down2->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );

    int nType2 = pNowItem1->type();
    QString sType2 = Probutility::GetDataInfoType(static_cast<PROTOCOLDATATYPE>(nType2));
    QString sMsg2 = pNowItem2->data(0).toString();
    QTableWidgetItem *up1 = new QTableWidgetItem(sType2,nType2);
    QTableWidgetItem *up2 = new QTableWidgetItem(sMsg2);
    up1->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );
    up1->setTextColor(QColor(30,144,255));
    up2->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );


    SubView->setItem(nMoveRow,0,up1);
    SubView->setItem(nMoveRow,1,up2);

    SubView->setItem(nNowRow,0,down1);
    SubView->setItem(nNowRow,1,down2);

    SubView->selectRow(nMoveRow);
    on_DataView_cellClicked(nMoveRow,0);

    saveSubData();
}

void ProtocolEditor::on_downBtn_clicked()
{
    auto SubView = FindViewItemByName("DataView");
    if(nullptr == SubView || SubView->rowCount() <= 1) return;

    auto pSubItems = SubView->selectedItems();
    if(pSubItems.isEmpty())  return;

    auto pItem = pSubItems.at(0);
    if(nullptr == pItem)return;

    int nNowRow = pItem->row();
    int nMoveRow = nNowRow + 1;
    if(nMoveRow > SubView->rowCount())
        return;

    //选中的items
    auto pNowItem1 = SubView->item(nNowRow,0);
    auto pNowItem2 = SubView->item(nNowRow,1);
    if(nullptr == pNowItem1 || nullptr == pNowItem2)
        return;

    //目标的items
    auto pMoveItem1 = SubView->item(nMoveRow,0);
    auto pMoveItem2 = SubView->item(nMoveRow,1);
    if(nullptr == pMoveItem1 || nullptr == pMoveItem2)
        return;

    int nType1 = pMoveItem1->type();
    QString sType1 = Probutility::GetDataInfoType(static_cast<PROTOCOLDATATYPE>(nType1));
    QString sMsg1 = pMoveItem2->data(0).toString();
    QTableWidgetItem *down1 = new QTableWidgetItem(sType1,nType1);
    QTableWidgetItem *down2 = new QTableWidgetItem(sMsg1);
    down1->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );
    down1->setTextColor(QColor(30,144,255));
    down2->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );

    int nType2 = pNowItem1->type();
    QString sType2 = Probutility::GetDataInfoType(static_cast<PROTOCOLDATATYPE>(nType2));
    QString sMsg2 = pNowItem2->data(0).toString();
    QTableWidgetItem *up1 = new QTableWidgetItem(sType2,nType2);
    QTableWidgetItem *up2 = new QTableWidgetItem(sMsg2);
    up1->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );
    up1->setTextColor(QColor(30,144,255));
    up2->setTextAlignment(Qt::AlignLeft |Qt::AlignVCenter );


    SubView->setItem(nMoveRow,0,up1);
    SubView->setItem(nMoveRow,1,up2);

    SubView->setItem(nNowRow,0,down1);
    SubView->setItem(nNowRow,1,down2);

    SubView->selectRow(nMoveRow);
    on_DataView_cellClicked(nMoveRow,0);

    saveSubData();
}

void ProtocolEditor::saveSubData()
{
    int nSysId = GetCurSelectSysItemId();
    //获取子系统id
    auto SubView = FindViewItemByName("MsgView");
    if(nullptr == SubView) return ;

    int nRow = SubView->currentRow();
    auto pSubItems = SubView->item(nRow,0);
    if(nullptr == pSubItems)return ;

    auto DataInfoView = FindDataInfoViewByName("DataInfoView");
    if(nullptr == DataInfoView) return;

    int nSubId = pSubItems->data(Qt::DisplayRole).toInt();
    int nType = pSubItems->type();

    QString sFileName;
    const char FileNameBuff[32] = "%d.xml";
    sFileName.sprintf(FileNameBuff,nSysId);
    const QString sSubFilePaht = QCoreApplication::applicationDirPath()+"/Systems/"+sFileName;
    QFile subFile(sSubFilePaht);
    if(!subFile.open(QIODevice::ReadWrite))return;

    std::vector<MsgDataInfo> msgDatas;


    auto DataView = FindViewItemByName("DataView");
    if(nullptr == DataView || DataView->rowCount() < 1) return;
    for(auto nRow = 0; nRow < DataView->rowCount();++nRow){
        auto pItem1 = DataView->item(nRow,0);
        auto pItem2 = DataView->item(nRow,1);
        if(nullptr == pItem1 || nullptr == pItem2)
            continue;
        MsgDataInfo data;
        data.nType = pItem1->type();
        data.sName = pItem2->data(0).toString();
        msgDatas.emplace_back(data);
    }

    QDomDocument doc;
    if(!doc.setContent(&subFile)) return;
    subFile.close();

    QDomElement root=doc.documentElement();
    QDomNodeList list=doc.elementsByTagName(FileSubTag);

    for(int i=0;i<list.count();i++)
    {
        QDomElement e=list.at(i).toElement();
        if(e.attribute("id").toInt()==nSubId &&  e.attribute("type").toInt() == nType )
        {
            QDomNodeList childE = e.elementsByTagName("Data");
            int nCount = childE.count();

            for(int j = 0; j < nCount;++j)
            {

                QDomElement childe = childE.at(j).toElement();
                INT nType = childe.attribute("type").toInt();
                QString sMsg = childe.attribute("name");
                QString sTextInfo = childe.toElement().text();

                for(auto it = msgDatas.begin();it != msgDatas.end();++it)
                {

                   if(it->nType == nType &&  sMsg == it->sName)
                   {
                       if(!sTextInfo.isEmpty())
                       {
                           it->sData = sTextInfo;
                       }
                   }
                }
            }
            break;
        }
    }


    for(auto it = msgDatas.begin();it != msgDatas.end();++it)
    {
       qDebug()<<"nType:"<<it->nType<<"sMsg:"<<it->sName<<" sTextInfo:"<<it->sData;
    }



    for(int i=0;i<list.count();i++)
    {
        QDomElement e=list.at(i).toElement();
        if(e.attribute("id").toInt()==nSubId &&  e.attribute("type").toInt() == nType )
        {
            QDomNodeList childE = e.elementsByTagName("Data");
            int nCount = childE.count();
            for(int j = 0; j < nCount;++j)
             e.removeChild(childE.at(0));
            break;
        }
    }

    if(!subFile.open(QFile::WriteOnly|QFile::Truncate))
        return;
      //输出到文件
    QTextStream out_stream(&subFile);
    doc.save(out_stream,4); //缩进4格
    subFile.close();

    resaveSubData(msgDatas);


}

void ProtocolEditor::resaveSubData(std::vector<MsgDataInfo>& datas)
{
    int nSysId = GetCurSelectSysItemId();
    const auto& pSubItem = GetCurSelectSysSubItem();
    if(nSysId < 0 || nullptr == pSubItem) return;

    int nSubId =pSubItem->data(Qt::DisplayRole).toInt();
    int nSubType =pSubItem->type();

    if(!QFile::exists(GetSubFilePath()+QString::number(nSysId)+".xml"))
        return;
    QFile file(GetSubFilePath()+QString::number(nSysId)+".xml");

    if(!file.exists())return;

    if(!file.open(QFile::ReadWrite))
        return;

    QDomDocument doc;
    if(!doc.setContent(&file))
    {
        file.close();
        return ;
    }
    file.close();

    QDomElement root=doc.documentElement();
    QDomNodeList list=doc.elementsByTagName(FileSubTag);

    //遍历查找子系统
    for(int i=0;i<list.count();i++)
    {
        QDomElement e=list.at(i).toElement();
        if(e.attribute("id").toInt()==nSubId &&e.attribute("type").toInt() == nSubType )
        {

            for(auto it = datas.begin();it != datas.end();++it)
            {
                QDomElement dataE = doc.createElement("Data");
                dataE.setAttribute("name",it->sName);
                dataE.setAttribute("type",it->nType);
                QDomElement InfoE = doc.createElement("CType");
                QDomCDATASection cData = doc.createCDATASection(it->sData);
                InfoE.appendChild(cData);
                dataE.appendChild(InfoE);
                e.appendChild(dataE);
            }

            break;
        }
    }
    if(!file.open(QFile::WriteOnly|QFile::Truncate)) //先读进来，再重写，如果不用truncate就是在后面追加内容，就无效了
        return;

    //输出到文件
    QTextStream out_stream(&file);
    doc.save(out_stream,4); //缩进4格
    file.close();
}
